var document = this.document;
const antd = require('antd-mobile'),
    ANY_TYPE = ['string', 'number', 'boolean', 'array', 'color', 'object'],
    GENERAL_BLOCKOPTIONS = { callMethodLabel: false },
    EVENTS = {
        onClick: '被点击',
        onTitleClick: '标题被点击',
        onTextClick: '文本被点击',
        onVideoClick: '视频被点击',
        onImgClick: '图片被点击',
        onDescriptionClick: '补充文本被点击',
    };

const types = {
    type: 'WATERFALL_FLOW_FRAME_SIMPLICITY_XJ',
    icon: 'icon-widget-list-viewer',
    title: '瀑布流框-简约',
    version: '1.0.0',
    author: 'XJ王大哥(2357942846)',
    docs: {
        url: '文档还没写...',
    },
    isInvisibleWidget: false,
    isGlobalWidget: false,
    properties: [
        {
            key: 'column',
            label: '列数',
            valueType: 'number',
            defaultValue: 2,
        },
        {
            key: 'background',
            label: '默认背景',
            valueType: 'color',
            defaultValue: 'rgba(172, 252, 231, 1)',
        },
        {
            key: 'borderRadius',
            label: '默认圆角',
            valueType: 'number',
            defaultValue: 20,
        },
        {
            key: 'ellipsisRows',
            label: '默认正文展示行数',
            valueType: 'number',
            defaultValue: 3,
        },
    ],
    methods: [
        {
            key: 'getData',
            params: [],
            valueType: ANY_TYPE,
            blockOptions: {
                ...GENERAL_BLOCKOPTIONS,
                color: 'rgba(249, 204, 55, 1)',
                icon: 'https://static.codemao.cn/xj/SyuVSMzi6.image/svg+xml',
            },
        },
        {
            key: 'getId',
            params: [],
            valueType: ANY_TYPE,
            blockOptions: {
                ...GENERAL_BLOCKOPTIONS,
                color: 'rgba(0, 175, 195, 1)',
                icon: 'https://static.codemao.cn/xj/SJD88zMop.image/svg+xml',
            },
        },
    ],
    events: [
        {
            key: 'onError',
            label: '出错',
            params: [{ key: 'error', label: '信息', valueType: 'string' }],
        },
        ...Object.entries(EVENTS).map(([key, label]) => ({
            key,
            label,
            params: [
                { key: 'number', label: '行', valueType: 'number' },
                ...(key === 'onImgClick' ? [{ key: 'imgNumber', label: '图片序号', valueType: 'number' }] : []),
            ],
        })),
    ],
};

class Widget extends VisibleWidget {
    constructor(p) {
        super(p);
        Object.assign(this, p);

        this.data = [];

        this.data = [
            {
                title: '标题', // 标题
                text: '正文', // 正文
                img: 'https://static.codemao.cn/whale/SyGeXMJFnVp', // 图片链接 或 图片链接列表
                video: 'https://kn-cdn.codemao.cn/creation/lesson/5_kitten_game/lesson06.mp4', // 视频链接(优先于图片)
                description: '补充文本', // 补充文本
            },
            {
                title: '标题', // 标题
                text: '正文比较多多多多多多多多多多多多多多多多多多多多多多多多多多多多多多多多', // 正文
                img: 'https://static.codemao.cn/whale/SyGeXMJFnVp', // 图片链接 或 图片链接列表
                description: '补充文本', // 补充文本
            },
            {
                title: '标题', // 标题
                text: '正文', // 正文
                img: 'https://static.codemao.cn/whale/SyGeXMJFnVp', // 图片链接 或 图片链接列表
                video: 'https://kn-cdn.codemao.cn/creation/lesson/5_kitten_game/lesson06.mp4', // 视频链接(优先于图片)
                description: '补充文本', // 补充文本
            },
        ];
    }

    getData() {
        return this._data;
    }

    getId() {
        return this.__widgetId;
    }

    /** 从get中检测data是否变化 */
    get _data() {
        if (this.arrayEquality(this.data, this.oldData))
            this.setProps({ oldData: JSON.parse(JSON.stringify(this.data)) });
        return this.data;
    }

    set _data(v) {
        this.data = v;
    }

    /** 判断两个数组是否相等 */
    arrayEquality(array, array2) {
        if (array?.length !== array?.length || JSON.stringify(array) !== JSON.stringify(array2)) {
            return true;
        }
        return false;
    }

    /** 设置自身node和子node */
    setNode(el) {
        this.node = el;
        this.nodes = [...this.node.childNodes];
    }

    /** 触发事件，接收多个index，并传入index+1 */
    emitClick(name, ...indexArray) {
        this.emit(name, ...indexArray.map(v => v + 1));
    }

    /**
     * 插值替换
     * @param {String | Object} text 欲处理的文本或对象，对象会处理所有值
     * @param  {...Object} env 插值从中取值，多个相同属性后面的会将前面的覆盖
     * @return {String | Object} 处理后的文本或对象
     * @example bracesReplace('替换文本：{{a}}', {a: '0'}, {a: '1'}) // 返回：替换文本：1
     */
    bracesReplace(text, ...env) {
        env = Object.assign(this, ...env);

        const caretReplace = v => v.replace(/{{.*?}}/g, v => env[v.slice(2, v.length - 2)]);

        if (typeof text === 'object') {
            for (const i in text) text[i] = caretReplace(text[i]);
            return text;
        } else {
            return caretReplace(text);
        }
    }

    waterfallHandler() {
        const width = this.__width / this.column,
            heightArr = Array(this.column).fill(0);
        this.nodes.forEach(v => {
            const height = v.getBoundingClientRect().height,
                minHeight = Math.min(...heightArr),
                minIndex = heightArr.indexOf(minHeight);

            v.style.cssText += `top: ${minHeight}px;left: ${minIndex * width}px;`;

            heightArr[minIndex] += height + 10;
        });
    }

    render() {
        const widget = `#${this.__widgetId} > #body`,
            style = {
                css: `
${widget}::-webkit-scrollbar {
    display: none
}
            `,
                body: {
                    height: '100%',
                    width: '100%',
                    position: 'relative',
                    overflow: 'auto',
                    scrollBehavior: 'smooth',
                },
                item: {
                    width: `${(this.__width - (this.column + 1) * 10) / this.column}px`,
                    background: 'linear-gradient(to bottom right, #fff 50%, {{background}})',
                    boxShadow: '4px 4px 30px rgba(0, 0, 0, 0.2)',
                    borderRadius: '{{borderRadius}}px',
                    padding: '15px',
                    margin: '10px',
                    verticalAlign: 'top',
                    position: 'absolute',
                },
                title: {
                    fontSize: '15px',
                    fontWeight: 'bold',
                },
                text: {
                    fontSize: '13px',
                    marginTop: '3px',
                    wordWrap: 'break-word',
                    wordBreak: 'break-all',
                },
                img: {
                    width: '100%',
                    marginTop: '3px',
                    borderRadius: '10px',
                    '--border-radius': '10px',
                },
                description: {
                    marginTop: '3px',
                    fontSize: '11px',
                    color: '#808080',
                },
                imgDrop: {
                    // 图片防拖拽
                    userSelect: 'none',
                    WebkitUserDrag: 'none',
                },
            };
        try {
            return (
                <>
                    <antd.Grid
                        ref={el => {
                            if (!el) return;
                            this.setNode(el);
                            this.waterfallHandler();
                        }}
                        columns={this.column}
                        gap={10}
                        style={style.body}
                        id="body">
                        {this.data.map((item, index) => (
                            <antd.Grid.Item
                                style={this.bracesReplace(style.item, item)}
                                onClick={this.emitClick.bind(this, 'onClick', index)}>
                                <span style={style.title} onClick={this.emitClick.bind(this, 'onTitleClick', index)}>
                                    {item.title}
                                </span>
                                <antd.Ellipsis
                                    direction="end"
                                    style={style.text}
                                    content={item.text}
                                    rows={this.bracesReplace('{{ellipsisRows}}', item)}
                                    expandText="展开"
                                    collapseText="收起"
                                    onClick={this.emitClick.bind(this, 'onTextClick', index)}
                                />
                                {'video' in item ? (
                                    <video
                                        style={style.img}
                                        src={item.video}
                                        controls
                                        autoplay
                                        onClick={this.emitClick.bind(this, 'onVideoClick', index)}
                                    />
                                ) : (
                                    <antd.Swiper style={style.img}>
                                        {(typeof item.img === 'string' ? [item.img] : item.img)?.map(
                                            (item, imgIndex) => (
                                                <antd.Swiper.Item
                                                    key={imgIndex}
                                                    onClick={this.emitClick.bind(this, 'onImgClick', index, imgIndex)}>
                                                    <img src={item} style={style.imgDrop} />
                                                </antd.Swiper.Item>
                                            )
                                        )}
                                    </antd.Swiper>
                                )}
                                <span
                                    style={style.description}
                                    onClick={this.emitClick.bind(this, 'onDescriptionClick', index)}>
                                    {item.description}
                                </span>
                            </antd.Grid.Item>
                        ))}
                    </antd.Grid>
                    <style
                        dangerouslySetInnerHTML={{
                            __html: `
                    
                    `,
                        }}></style>
                </>
            );
        } catch (e) {
            this.emit('onError', e);
            console.error(e);
        }
    }
}

exports.types = types;
exports.widget = Widget;
